package com.data_structure_test.queue;

/**
 * 1.哨兵问题   2. 指针处理问题
 */
public class MyCircularDeque {

    private int[] array;

    private int size;

    private int startIndex;

    private int endIndex;

    /** Initialize your data structure here. Set the size of the deque to be k. */
    public MyCircularDeque(int k) {
        array = new int[k];
        size = 0;
        startIndex = 0;
        endIndex = 0;
    }

    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    public boolean insertFront(int value) {
        if(isFull()){
            return false;
        }
        if(!isEmpty()) {
            startIndex = formerIndex(startIndex);
        }
        array[startIndex] = value;
        size ++;
        return true;
    }

    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    public boolean insertLast(int value) {
        if(isFull()){
            return false;
        }
        if(!isEmpty()){
            endIndex = nextIndex(endIndex);
        }
        array[endIndex] = value;
        size ++;
        return true;
    }

    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    public boolean deleteFront() {
        if(isEmpty()){
            return false;
        }
        array[startIndex] = 0;
        size --;
        if(startIndex != endIndex){
            startIndex = nextIndex(startIndex);
        }
        return true;
    }

    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    public boolean deleteLast() {
        if(isEmpty()){
            return false;
        }
        array[endIndex] = 0;
        size -- ;
        if(startIndex != endIndex){
            endIndex = formerIndex(endIndex);
        }
        return true;
    }

    /** Get the front item from the deque. */
    public int getFront() {
        if(isEmpty()){
            return -1;
        }
        return array[startIndex];
    }

    /** Get the last item from the deque. */
    public int getRear() {
        if(isEmpty()){
            return -1;
        }
        return array[endIndex];
    }

    /** Checks whether the circular deque is empty or not. */
    public boolean isEmpty() {
        return size == 0;
    }

    /** Checks whether the circular deque is full or not. */
    public boolean isFull() {
        return size == array.length;
    }

    private int nextIndex(int curr){
        return (++curr)%array.length;
    }

    private int formerIndex(int curr){
        return curr == 0? array.length - 1:--curr;
    }
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque obj = new MyCircularDeque(k);
 * boolean param_1 = obj.insertFront(value);
 * boolean param_2 = obj.insertLast(value);
 * boolean param_3 = obj.deleteFront();
 * boolean param_4 = obj.deleteLast();
 * int param_5 = obj.getFront();
 * int param_6 = obj.getRear();
 * boolean param_7 = obj.isEmpty();
 * boolean param_8 = obj.isFull();
 */
